﻿using System;

using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Resources;
using Windows.UI.ApplicationSettings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

using SeriesManager.View;
using SeriesManager.ViewModel;
using WinRTFramework;
using WinRTFramework.FrameworkConfiguration;
using WinRTFramework.Common;
using SeriesManager.Framework;

namespace SeriesManager.GUI
{
    sealed partial class App : Application, IApplicationAdapter
    {
        public event EventHandler<WinRTFramework.Common.ResumePreviousAppState> AfterResume;
        public event EventHandler BeforeSuspend;

        private WinRTContainer _winRtContainer;

        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
            this.Resuming += OnResuming;
            SuspensionManager.KnownTypes.Add(typeof(int[]));
        }

        private async void OnSuspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
        {
            if (this.BeforeSuspend != null)
            {
                this.BeforeSuspend(this, EventArgs.Empty);
            }

            var deferral = e.SuspendingOperation.GetDeferral();
            await SuspensionManager.SaveAsync();
            deferral.Complete();
        }

        private void OnResuming(object sender, object e)
        {
            if (this.AfterResume != null)
            {
                this.AfterResume(this, WinRTFramework.Common.ResumePreviousAppState.Suspended);
            }
        }

        protected override async void OnLaunched(LaunchActivatedEventArgs args)
        {
            var rootFrame = (FrameView)Window.Current.Content;

            if (rootFrame == null)
            {
                var splashViewModel = new SplashViewModel();
                var splashView = new SplashView() { DataContext = splashViewModel };
                Window.Current.Content = splashView;
                Window.Current.Activate();

                await splashViewModel.DoWork();

                rootFrame = new FrameView();
                _winRtContainer = new WinRTContainer(this, rootFrame.Navi, new IoCAdapter(), new ViewViewModelMapper(new IoCAdapter()));
                
                var frameViewModel = new FrameViewModel();
                frameViewModel.NavigationService = _winRtContainer.NavigationService;
                frameViewModel.SettingService = _winRtContainer.SettingService;
                rootFrame.DataContext = frameViewModel;

                Window.Current.Content = rootFrame;

                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    try 
                    { 
                        // Buggy :-(
                        //await SuspensionManager.RestoreAsync(); 
                    }
                    catch (SuspensionManagerException) 
                    {
                    }
                }
            }

            if (rootFrame.Navi.Content == null)
            {
                if (!_winRtContainer.NavigationService.Navigate<SubscriptionViewModel>())
                {
                    throw new Exception("Failed to create initial page");
                }
            }
                
            if (!string.IsNullOrEmpty(args.Arguments))
            {
                foreach (var series in AppX.Instance.Series)
                {
                    if (series.ID.ToString() == args.Arguments)
                    {
                        AppX.Instance.Current = series;
                        _winRtContainer.NavigationService.Navigate<SeriesViewModel>(series.ID);
                        break;
                    }
                }
            }

            if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                AfterResume(this, ResumePreviousAppState.Terminated);
            }
        }
    }
}
